﻿using UnityEngine;
using System.Collections;
using System.Threading.Tasks;
using IMMotors;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.ResourceManagement.AsyncOperations;


public class Item : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public static bool bCleaning = false;

    //public static bool bEnableClean = true;
    bool bTaskCompleted = false;

    public ItemActionType itemActionType;

    public Vector3 StartScale;

    public float startRotation;
    public float endRotation;
    public float endScaleFactor = 1;


    bool bDrag = false;
    public Vector3 StartPosition;
    public Transform EndPosition;
    public float SnapItemOffset = 1.13f; //0.3


    Transform StartParent;
    Transform ActiveToolParent;
    RectTransform recTransform;
    float x;
    float y;
    Vector3 diffPos = new Vector3(0, 0, 0);

    public static float TopBorder;
    public static float LeftBorder;

    int sortingOrder = 0;
    public string itemHolder = "";
    public bool destroyWithItemHolder = false;
    public string DepnedentItemsList = "";

    public string ContainingItemsList = "";

    public Transform[] alternativeEndPositions;
    public string alternativePrefabsName = "";
    public string selectedAltPrefabName = "";

    void Start()
    {
        bCleaning = false;
        sortingOrder = transform.GetComponent<Renderer>().sortingOrder;
    }

    void Update()
    {
        if (GameData.bOutOfTime && bDrag)
        {
            StartCoroutine("MoveBack");
            bDrag = false;
        }
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (bTaskCompleted) return;

        if (RoomScene.bPause || CleaningTool.activeToolNo > 0 || MenuManager.activeMenu != "")
            return;

        if (Tutorial.bTutorial && GameData.TutorialShown == 0)
        {
            if (Tutorial.TutorialPhase == 4 && itemActionType == ItemActionType.changeSprite &&
                transform.name == Tutorial.Instance.F2Start.transform.GetChild(0).name)
            {
                Tutorial.TutorialPhase = 5;
                ChangeSprite();
                SoundManager.Instance.Play_ToolClick();
                return;
            }
            else return;
        }

        if (!GameData.bOutOfTime)
        {
            if (itemActionType == ItemActionType.eraseSprite)
            {
                EraseSprite();
            }
            else if (itemActionType == ItemActionType.rotate)
            {
                Rotate();
                SoundManager.Instance.Play_ToolClick();
            }
            else if (itemActionType == ItemActionType.changeSprite) ChangeSprite();
        }
    }

    void SetGlow()
    {
        GameObject.Find("GLOW").GetComponent<Glow>().ActiveItem = transform;
    }

    void ReleaseGlow()
    {
        GameObject.Find("GLOW").GetComponent<Glow>().ActiveItem = null;
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (bTaskCompleted || bMovingBack) return;
        if (!GameData.bOutOfTime)
        {
            if (RoomScene.bPause || CleaningTool.activeToolNo > 0 || MenuManager.activeMenu != "")
                return;

            if (Tutorial.bTutorial && GameData.TutorialShown == 0)
            {
                if (!(Tutorial.TutorialPhase == 7 && Tutorial.Instance.F3Start.transform.childCount == 1 &&
                      transform.name == Tutorial.Instance.F3Start.transform.GetChild(0).name))
                {
                    //Tutorial.TutorialPhase = 7;
                    return;
                }
                //else return;
            }

            SoundManager.Instance.Play_ToolClick();
            //Debug.Log ("DRAG");
            if (itemActionType == ItemActionType.move || itemActionType == ItemActionType.moveAndChangeSprite ||
                itemActionType == ItemActionType.dispose)
            {
                bCleaning = false;
                bDrag = true;

                diffPos = transform.position - Camera.main.ScreenToWorldPoint(Input.mousePosition);
                diffPos = new Vector3(diffPos.x, diffPos.y, 0);

                transform.GetComponent<Renderer>().sortingOrder = 10;
                transform.GetComponent<Renderer>().sortingLayerName = "MOVE";


                SetGlow();
            }
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (bTaskCompleted) return;
        if (!GameData.bOutOfTime)
        {
            if (bDrag)
            {
//				Debug.Log(bDrag +" sdfs");
                x = Input.mousePosition.x;
                y = Input.mousePosition.y;

                Vector3 pos = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 100.0f)) + diffPos;


                if (pos.x <= LeftBorder) pos.x = LeftBorder;
                if (pos.y >= TopBorder) pos.y = TopBorder;
                pos.z = 0;
                transform.position = pos; //100 - canvas plane distance
            }
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (bTaskCompleted) return;
        if (!GameData.bOutOfTime)
        {
            if (bDrag)
            {
                bDrag = false;

                if (!GameData.bOutOfTime)
                {
                    Collider2D[] hitColliders = null;
                    if (itemActionType == ItemActionType.dispose)
                    {
                        hitColliders = Physics2D.OverlapCircleAll(transform.position, .5f,
                            1 << LayerMask.NameToLayer("Trash"));

                        if (hitColliders != null && hitColliders.Length > 0)
                        {
                            StartCoroutine(FadeOutSprite(0, 0.2f));
                        }
                        else
                        {
                            SoundManager.Instance.Play_Error();
                            StartCoroutine("MoveBack");
                        }
                    }


                    if (itemActionType == ItemActionType.move || itemActionType == ItemActionType.moveAndChangeSprite)
                    {
                        //Debug.Log(transform.position +"  "+  EndPosition.name+ "  " + EndPosition.position);
                        if (EndPosition.childCount == 0 &&
                            Vector3.Distance(transform.position, EndPosition.position) < SnapItemOffset)
                        {
                            if (itemHolder != "" && GameObject.Find(itemHolder) == null)
                            {
                                SoundManager.Instance.Play_Error();
                                StartCoroutine("MoveBack");
                            }
                            else
                            {
                                StartCoroutine("SnapToPosition");
                                if (Tutorial.TutorialPhase == 7) Tutorial.TutorialPhase = 8;
                            }
                        }
                        else if (alternativeEndPositions.Length > 0)
                        {
                            for (int i = 0; i < alternativeEndPositions.Length; i++)
                            {
                                if (alternativeEndPositions[i].childCount == 0 &&
                                    Vector3.Distance(transform.position, alternativeEndPositions[i].position) <
                                    SnapItemOffset)
                                {
                                    EndPosition = alternativeEndPositions[i];
                                    selectedAltPrefabName = alternativePrefabsName.Split(new char[] { ';' },
                                        System.StringSplitOptions.RemoveEmptyEntries)[i];
                                    StartCoroutine("SnapToPosition");
                                    break;
                                }

                                if (selectedAltPrefabName == "")
                                {
                                    SoundManager.Instance.Play_Error();
                                    StartCoroutine("MoveBack");
                                }
                            }
                        }
                        else
                        {
                            SoundManager.Instance.Play_Error();
                            //Debug.Log("MoveBack");
                            StartCoroutine("MoveBack");
                        }
                    }
                }
                else
                {
                    //isteklo je vreme
                    StartCoroutine("MoveBack");
                }
            }
        }
    }

    IEnumerator SnapToPosition()
    {
        bCleaning = true;
        bTaskCompleted = true;
        RoomScene.bTaskAnim = true;
        //zaustavljanje vremena ako je poslednji task
        if (GameData.CompletedTasks + 1 == GameData.TotalTasks)
        {
            RoomScene.bPause = true;
        }

        yield return new WaitForEndOfFrame();
        float pom = 0;
        while (pom < 1)
        {
            pom += 0.02f * 5;
            transform.position = Vector3.Lerp(transform.position, EndPosition.position, pom);
            yield return new WaitForSeconds(0.02f);
        }

        transform.position = EndPosition.position;


        Camera.main.SendMessage("TaskCompleted", transform.position);

        if (itemActionType == ItemActionType.moveAndChangeSprite)
        {
            GameObject go;
            string prefabName = string.IsNullOrEmpty(selectedAltPrefabName)
                ? transform.name.Replace("_A", "_B")
                : selectedAltPrefabName;
            string assetName = $"Room{RoomScene.selectedRoom}/{prefabName}.prefab";
            var handle = Addressables.LoadAssetAsync<GameObject>(assetName);
            yield return handle.Task.AsCoroutine();
            if (handle.Status != AsyncOperationStatus.Succeeded)
            {
                Debug.LogError("Failed to load prefab: " + assetName);
                yield break;
            }

            go = Instantiate(handle.Result, EndPosition);
            // if (selectedAltPrefabName == "")
            // {
            //     // go = Instantiate(Resources.Load(
            //     //     "Items/Room" + RoomScene.selectedRoom.ToString() + "/" + transform.name.Replace("_A", "_B"),
            //     //     typeof(GameObject))) as GameObject;
            //     // go = AAMgr.Instance.InstantiateAsync($"Room{RoomScene.selectedRoom}/{transform.name.Replace("_A", "_B")}.prefab").AsCoroutine();
            // }
            // else
            // {
            //     go = Instantiate(Resources.Load(
            //         "Items/Room" + RoomScene.selectedRoom.ToString() + "/" + selectedAltPrefabName,
            //         typeof(GameObject))) as GameObject;
            // }

            EndPosition.localScale = Vector3.one;
            go.transform.localPosition = Vector3.zero;

            go.transform.localScale = transform.localScale * endScaleFactor;
            go.transform.Rotate(new Vector3(0, 0, endRotation));
            go.transform.GetComponent<Collider2D>().enabled = false;
            go.GetComponent<Item>().enabled = false;


            if (itemHolder != "" && GameObject.Find(itemHolder) != null)
            {
                GameObject ith = GameObject.Find(itemHolder);
                if (destroyWithItemHolder)
                {
                    go.transform.SetParent(ith.transform);
                }

                ith.GetComponent<Item>().ContainingItemsList +=
                    transform.name.Replace("_A", "_B") + ";"; //.Replace("(Clone)","");
                //Debug.Log(" LISTA :  "+ith.GetComponent<Item>().ContainingItemsList );
            }

            transform.GetComponent<SpriteRenderer>().enabled = false;

            bCleaning = false;
            ReleaseGlow();
            Destroy(gameObject);
        }
        else
        {
            EndPosition.localScale = Vector3.one;
            transform.SetParent(EndPosition);
            transform.localPosition = Vector3.zero;

            transform.GetComponent<Renderer>().sortingOrder = sortingOrder;
            transform.GetComponent<Renderer>().sortingLayerName = "Default";
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, endRotation));
            transform.localScale = transform.localScale * endScaleFactor;

            GetComponent<Collider2D>().enabled = false;
            enabled = false;

            if (itemHolder != "" && GameObject.Find(itemHolder) != null)
            {
                GameObject ith = GameObject.Find(itemHolder);
                if (destroyWithItemHolder)
                {
                    transform.SetParent(ith.transform);
                }

                ith.GetComponent<Item>().ContainingItemsList +=
                    transform.name.Replace("_A", "_B") + ";"; //.Replace("(Clone)","");
                //Debug.Log(" LISTA :  "+ith.GetComponent<Item>().ContainingItemsList );
            }
        }

        ReleaseGlow();

        yield return new WaitForSeconds(0.5f);
        bCleaning = false;
    }

    bool bMovingBack = false;

    IEnumerator MoveBack()
    {
        if (!bMovingBack)
        {
            bMovingBack = true;
            yield return new WaitForEndOfFrame();
            ReleaseGlow();
            float pom = 0;
            while (pom < 1)
            {
                pom += 0.02f * 5;
                transform.position = Vector3.Lerp(transform.position, StartPosition, pom);
                yield return new WaitForSeconds(0.02f);
            }

            transform.position = StartPosition;

            transform.GetComponent<Renderer>().sortingOrder = sortingOrder;
            transform.GetComponent<Renderer>().sortingLayerName = "Default";
            bMovingBack = false;
        }
    }

    async void ChangeSprite()
    {
        bool AllDepnedentItems = true;
        if (DepnedentItemsList != "")
        {
            string[] list = DepnedentItemsList.Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < list.Length; i++)
            {
                //if(transform.FindChild(list[i]) == null) { AllDepnedentItems = false;break;}
                if (!ContainingItemsList.Contains(list[i] + ";"))
                {
                    AllDepnedentItems = false;
                    break;
                }
            }
        }

        if (!AllDepnedentItems)
        {
            SoundManager.Instance.Play_Error();
        }

        else
        {
            //zaustavljanje vremena ako je poslednji task
            if (GameData.CompletedTasks + 1 == GameData.TotalTasks)
            {
                RoomScene.bPause = true;
            }

            // GameObject go =
            //     Instantiate(Resources.Load(
            //         "Items/Room" + RoomScene.selectedRoom.ToString() + "/" + transform.name.Replace("_A", "_B"),
            //         typeof(GameObject))) as GameObject;
            GameObject go = await AAMgr.Instance.InstantiateAsync($"Room{RoomScene.selectedRoom}/{transform.name.Replace("_A", "_B")}.prefab");

            EndPosition.localScale = Vector3.one;
            go.transform.parent = EndPosition;
            go.transform.localPosition = Vector3.zero;

            transform.localScale = transform.localScale * endScaleFactor;

            go.transform.localScale = transform.localScale * endScaleFactor;

            go.transform.Rotate(new Vector3(0, 0, endRotation));
            go.transform.GetComponent<Collider2D>().enabled = false;
            go.transform.GetComponent<Item>().enabled = false;

            bTaskCompleted = true;
            RoomScene.bTaskAnim = true;
            Camera.main.SendMessage("TaskCompleted", transform.position);

            SoundManager.Instance.Play_ToolClick();
            StartCoroutine("CiscenjeJeUToku");
            transform.GetComponent<SpriteRenderer>().enabled = false;
            //GameObject.Destroy(gameObject);
        }
    }

    IEnumerator CiscenjeJeUToku()
    {
        bCleaning = true;
        yield return new WaitForSeconds(0.5f);
        bCleaning = false;
        if (transform.GetComponent<SpriteRenderer>().enabled == false) Destroy(gameObject);
    }

    bool bRotated = false;

    public void Rotate()
    {
        if (!bRotated)
        {
            bRotated = true;
            StartCoroutine(RotateSprite(0.05f, .2f));
            //particles
        }
    }

    IEnumerator RotateSprite(float waitTime, float rotateTime)
    {
        bTaskCompleted = true;
        RoomScene.bTaskAnim = true;
        bCleaning = true;
        SetGlow();
        //zaustavljanje vremena ako je poslednji task
        if (GameData.CompletedTasks + 1 == GameData.TotalTasks)
        {
            RoomScene.bPause = true;
        }

        yield return new WaitForSeconds(waitTime);

        Vector3 rotationStep = new Vector3(0, 0, (endRotation - startRotation) * rotateTime / 20f);
//		Debug.Log(startRotation + "  "+ endRotation + "  " + rotationStep);
        int i = 0;


        Quaternion startR = Quaternion.Euler(0, 0, startRotation);
        Quaternion endR = Quaternion.Euler(0, 0, endRotation);

        float elapsedTime = 0;

        while (i < 1000 && elapsedTime <= 1)
        {
            i++;

            elapsedTime += Time.deltaTime / rotateTime;
            yield return new WaitForEndOfFrame();
            transform.rotation = Quaternion.Lerp(startR, endR, elapsedTime);
        }

        Camera.main.SendMessage("TaskCompleted", transform.position);


        transform.GetComponent<Collider2D>().enabled = false;
        this.enabled = false;
        ReleaseGlow();
        yield return new WaitForSeconds(0.5f);
        bCleaning = false;
    }

    public void EraseSprite()
    {
        bool AllDepnedentItems = true;
        if (DepnedentItemsList != "")
        {
            string[] list = DepnedentItemsList.Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < list.Length; i++)
            {
                if (transform.Find(list[i]) == null)
                {
                    AllDepnedentItems = false;
                    break;
                }
            }
        }

        if (!AllDepnedentItems)
        {
            SoundManager.Instance.Play_Error();
        }

        else
        {
            SoundManager.Instance.Play_ToolClick();
            bTaskCompleted = true;
            RoomScene.bTaskAnim = true;
            SetGlow();
            transform.GetComponent<Collider2D>().enabled = false;
            StartCoroutine(FadeOutSprite(0, 1));
        }
    }

    //OVU F_JU POZIVA KLASA CleaningTool
    public void FadeOut_CleaningTool()
    {
        transform.GetComponent<Collider2D>().enabled = false;
        StartCoroutine(FadeOutSprite(.3f, 1));
    }

    IEnumerator FadeOutSprite(float waitTime, float fadeTime)
    {
        bCleaning = true;
        //zaustavljanje vremena ako je poslednji task
        if (GameData.CompletedTasks + 1 == GameData.TotalTasks)
        {
            RoomScene.bPause = true;
        }

        yield return new WaitForSeconds(waitTime);
        SpriteRenderer spr = transform.GetComponent<SpriteRenderer>();

        SpriteRenderer[] sprChildren = new SpriteRenderer[transform.childCount];
        for (int i = 0; i < transform.childCount; i++)
        {
            sprChildren[i] = transform.GetChild(i).GetComponent<SpriteRenderer>();
        }

        float fadeStep = 0.05f / fadeTime;
        while (spr.color.a > 0)
        {
            yield return new WaitForSeconds(0.05f);
            Color col = new Color(1, 1, 1, spr.color.a - fadeStep);
            spr.color = col;
            for (int i = 0; i < transform.childCount; i++)
            {
                sprChildren[i].color = col;
            }
        }

        Camera.main.SendMessage("TaskCompleted", transform.position);
        ReleaseGlow();
        yield return new WaitForSeconds(0.5f);
        bCleaning = false;
        GameObject.Destroy(gameObject);
    }
}

public enum ItemActionType
{
    rotate,
    move,
    moveAndChangeSprite,
    dispose,
    clean,
    changeSprite,
    eraseSprite,
    hide,
    none
}
